/*
 * @Descripttion: GGB
 * @version: 1.0
 * @Author: GGB
 * @Date: 2022-01-16 16:20:39
 * @LastEditors: GGB
 * @LastEditTime: 2022-02-01 18:13:52
 */
// 样式

import './App.css';
// import './App.less';
// 组件
import { Col, Row, Button, Empty, Layout, Spin } from 'antd';

import FileSearch from './components/FileSearch';
import FileList from './components/FileList';
import ButtonBtn from './components/ButtonBtn';
import SimpleMDE from "react-simplemde-editor";

// 图标
import {
  FileAddTwoTone,
  FolderOpenTwoTone
} from '@ant-design/icons';
import TabList from './components/TabList';

// 库
import { v4 as uuidv4 } from 'uuid'

// 核心
import {
  useState
  // useRef
} from 'react'
import { objToArr, flattenArr, timestampToString } from './utils/helper';
import fileHelper from './utils/fileHelper';
import useIpcRenderer from './hooks/useIpcRenderer';

// node模块
const { join, basename, extname, dirname } = window.require('path')

// electron模块
const { app, dialog } = window.require('@electron/remote')
const { ipcRenderer } = window.require('electron')


// 子组件
const { Header, Footer, Sider, Content } = Layout;

// 本地持久化缓存模块
const Store = window.require('electron-store')
const fileStore = new Store({ name: 'Files Data' })
const settingsStore = new Store({ name: 'Settings' })
// // 保存持久缓存
const saveFilesToStore = (files) => {
  const filesStoreObj = objToArr(files).reduce((result, file) => {
    const { id, path, title, createdAt, isSynced, updatedAt } = file
    result[id] = { id, path, title, createdAt, isSynced, updatedAt }
    return result
  }, {})
  fileStore.set('files', filesStoreObj)
}
// fileStore.clear()




function App() {
  // 文件
  const [files, setFiles] = useState(fileStore.get('files') || {})
  // 文件
  const [searchFiles, setSearchFiles] = useState([])
  // 激活文件
  const [activeFileID, setActiveFileID] = useState('')
  // 打开文件ids
  const [openedFileIDs, setOpenedFileIDs] = useState([])
  // 编辑过的文件ids
  const [unsavedFileIDs, setUnsaveFileIDs] = useState([])
  // 加载状态
  const [isLoading, setLoading] = useState(false)
  // 文件数组
  const filesArr = objToArr(files)
  // 文件保存路径
  const savedLocation = settingsStore.get('savedFileLocation') || app.getPath('documents')
  // 计算变量
  // 判断是否同步文件到七牛云
  const getAutoSync = () => ['enableAutoSync', 'accessKey', 'secretKey', 'bucketName'].every(key => !!settingsStore.get(key))
  // 打开的文件
  const openedFiles = openedFileIDs.map(openID => files[openID])
  // 文件列表
  const fileListArray = searchFiles.length ? searchFiles : filesArr
  // 当前编辑的文件
  const activeFile = filesArr.find(file => file.id === activeFileID)



  // 点击左边栏文件按钮
  const fileClick = (fileID) => {
    // set current active file
    setActiveFileID(fileID)
    const currentFile = files[fileID]
    const { id, title, path, isLoaded } = currentFile
    // 判断文件是否加载完成
    if (!isLoaded) {
      if (getAutoSync) {
        ipcRenderer.send('download-file', { key: `${title}.md`, path, id })
      } else {
        fileHelper.readFile(currentFile.path).then(value => {
          const newFile = { ...files[fileID], body: value, isLoaded: true }
          setFiles({ ...files, [fileID]: newFile })
        })
      }

    }
    // if openedFiles don't have the current ID
    if (!openedFileIDs.includes(fileID)) {
      // add new fileID to openedFiles
      setOpenedFileIDs([...openedFileIDs, fileID])
    }
  }

  // 右边文件切换
  const tabClick = (fileID) => {
    // set current active file
    setActiveFileID(fileID)
  }

  // 关闭tab
  const tabClose = (id) => {
    const tabsWithout = openedFileIDs.filter(fileID => fileID !== id)
    setOpenedFileIDs(tabsWithout)
    // set the active to first opened tab if still tabs left
    if (tabsWithout.length > 0) {
      setActiveFileID(tabsWithout[tabsWithout.length - 1])
    } else {
      setActiveFileID('')
    }


  }
  // fileChange
  const fileChange = (id, body) => {
    if (body === files[id].body) return
    const newFiles = { ...files[id], body }
    setFiles({ ...files, [id]: newFiles })
    // add new fileID to unsavedFileIDs
    if (!unsavedFileIDs.includes(id)) {
      setUnsaveFileIDs([...unsavedFileIDs, id])
    }

  }



  // delete File
  const deleteFile = (id) => {
    // 高级语法，高级得不得了
    const { [id]: value, ...afterDelete } = files;
    if (files[id].isNew) {
      setFiles(afterDelete)
    } else {
      // delete有问题
      // fileHelper.deleteFile(join(savedLocation, `${files[id].title}.md`)).then(() => { 
      fileHelper.deleteFile(files[id].path).then(() => {
        // 发起远程文件的删除
        let key=files[id].title
         ipcRenderer.send('delete-file', { key: `${key}.md`})
        setFiles(afterDelete)
        saveFilesToStore(afterDelete)
        // close the tab if open
        tabClose(id)
      })
    }

  }
  // 更新文件名
  const updateFileName = (id, title, isNew) => {
    //  newPath should be different based on isNew
    // if isNew is false, path should be old dirname +new title
    const newPath = isNew ? join(savedLocation, `${title}.md`)
      : join(dirname(files[id].path), `${title}.md`)
    const modifiedFile = { ...files[id], title, isNew: false, path: newPath }
    const newFiles = { ...files, [id]: modifiedFile }
    if (isNew) {
      fileHelper.writeFile(newPath, files[id].body).then(() => {
        setFiles(newFiles)
        saveFilesToStore(newFiles)
      })
    } else {
      const oldPath = files[id].path
      const oldTitle=files[id].title
      fileHelper.renameFile(oldPath, newPath).then(() => {
        // 同步远程 文件名
        ipcRenderer.send('rename-file', { key: `${oldTitle}.md`, targetKey:`${title}.md` })
        setFiles(newFiles)
        saveFilesToStore(newFiles)
      })
    }
  }

  const fileSearch = (keyword) => {
    // filter out the new files based on keyword
    const newFiles = filesArr.filter(file => file.title.includes(keyword))
    setSearchFiles(newFiles)
  }


  //  创建文件
  const createNewFile = () => {
    const newId = uuidv4()
    const newFile = {
      id: newId,
      title: '',
      body: '## 请输入markdwon',
      createdAt: new Date().getTime(),
      isNew: true
    }
    setFiles({ ...files, [newId]: newFile })
    // TODO 在新窗口打开
    // fileClick(newId)
  }

  const saveCurrentFile = () => {

    if (!activeFile) return
    const { path, body, title } = activeFile
    fileHelper.writeFile(path, body).then(() => {
      setUnsaveFileIDs(unsavedFileIDs.filter(id => id !== activeFile.id))
      if (getAutoSync) {
        ipcRenderer.send('upload-file', { key: `${title}.md`, path })
      }
    })
  }
  // 导入文件
  const importFiles = () => {
    dialog.showOpenDialog({
      title: '选择导入的 Markdown文件',
      properties: ['openFile', 'multiSelections'],
      filters: [
        {
          name: 'Markdown files',
          extensions: ['md']
        }
      ]
    }).then(({ canceled, filePaths }) => {
      // filter out the path we already have in electron store
      // ['/xxx/xxx/xxx',...]
      if (canceled || !filePaths.length) return
      const filteredPaths = filePaths.filter(path => {
        const alreadyAdded = Object.values(files).find(file => {
          return file.path === path
        })
        return !alreadyAdded
      })
      // extend the path array to an array contains files info
      // [{id:'',path:'',title:''},...]
      const importFilesArr = filteredPaths.map(path => {
        return {
          id: uuidv4(),
          title: basename(path, extname(path)),
          path
        }
      })

      // get the new files object in flattenArr
      const newFiles = { ...files, ...flattenArr(importFilesArr) }
      // setState and update electron store
      setFiles(newFiles)
      saveFilesToStore(newFiles)
      if (importFilesArr.length) {
        dialog.showMessageBox({
          type: 'info',
          title: `成功导入了${importFilesArr.length}个文件`,
          message: `成功导入了${importFilesArr.length}个文件`
        })
      }

    }).catch(err => {
      console.log(err)
    })
  }
  // 更新上传配置
  const activeFileUploaded = () => {
    const { id } = activeFile
    const modifiedFile = { ...files[id], isSynced: true, updatedAt: new Date().getTime() }
    const newFiles = { ...files, [id]: modifiedFile }
    setFiles(newFiles)
    saveFilesToStore(newFiles)
  }

  const activeFileDownloaded = (event, message) => {
    const currentFile = files[message.id]
    const { id, path } = currentFile
    fileHelper.readFile(path).then(value => {
      let newFile
      if (message.status === 'download-success') {
        newFile = { ...files[id], body: value, isLoaded: true, isSynced: true, updatedAt: new Date().getTime() }
      } else {
        newFile = { ...files[id], body: value, isLoaded: true }
      }
      const newFiles = { ...files, [id]: newFile }
      setFiles(newFiles)
      saveFilesToStore(newFiles)
    })
  }
  // 所有文件上传完毕之后更新的本地的内容
  const filesUploaded = () => { 
    const newFiles = objToArr(files).reduce((result, file) => { 
      const currentTime = new Date().getTime()
      result[file.id] = {
        ...files[file.id],
        isSynced: true,
        updatedAt:currentTime
      }
      return result
    }, {})
    setFiles(newFiles)
      saveFilesToStore(newFiles)
  }

  useIpcRenderer({
    'create-new-file': createNewFile,
    'save-edit-file': saveCurrentFile,
    'active-file-uploaded': activeFileUploaded,
    'import-file': importFiles,
    'file-downloaded': activeFileDownloaded,
    'loading-status': (message, status) => { setLoading(status) },
    'files-uploaded':filesUploaded
  })



  return (
    <Spin spinning={isLoading}   size="large" >
      <Layout className="h-100vh">
        <Sider className="d-flex flex-column left-pannel">
          <FileSearch title='我的云文档' onFileSearch={fileSearch}></FileSearch>
          <FileList
            className="flex-1"
            files={fileListArray}
            onFileClick={fileClick}
            onSaveEdit={updateFileName}
            onFileDelete={deleteFile}
          />
          <Row className="bottom-btn">
            <Col span={12}>
              <ButtonBtn
                className="no-border"
                type="primary"
                text="新建"
                icon={<FileAddTwoTone />}
                onClick={createNewFile} /></Col>
            <Col span={12}>
              <ButtonBtn
                className="no-border"
                icon={<FolderOpenTwoTone />}
                text="导入"
                onClick={importFiles} /></Col>
          </Row>
        </Sider>
        <Layout>

          {
            activeFile &&
            <>
              <Header className="d-flex align-item-center">
                <TabList
                  activeId={activeFileID}
                  unsaveIds={unsavedFileIDs}
                  files={openedFiles}
                  onTabClick={tabClick}
                  onCloseTab={tabClose}
                />
              </Header>
            </>
          }
          <Content>

            {
              !activeFile && <div className="empty">
                <Empty
                  image="https://gw.alipayobjects.com/zos/antfincdn/ZHrcdLPrvN/empty.svg"
                  imageStyle={{
                    height: 100,
                  }}
                  description={
                    <span>
                      <a href="#API">选择或创建新的Markdown文档</a>
                    </span>
                  }
                >
                  <Button type="primary">创建</Button>
                </Empty>
              </div>
            }
            {
              activeFile &&
              <SimpleMDE key={activeFileID} options={{ minHeight: '500px', autofocus: true }} value={activeFile.body} onChange={(value) => fileChange(activeFile.id, value)} />
            }


          </Content>

          {
            (activeFile && activeFile.isSynced) && <Footer>已同步 上次同步时间 {timestampToString(activeFile.updatedAt)}</Footer>
          }

        </Layout>
      </Layout>
    </Spin>
  );
}

export default App;
